#pragma once
#include <QDateTime>
#include <QList>
#include "KgLogFile.h"
#include "xnserial.h"
#include "comstruct.h"

typedef unsigned short 	UINT16;
typedef unsigned char 	UINT8;
typedef unsigned int 	UINT32;
typedef unsigned long 	UINT64; 

#define FAIL_COUNT_INITED            1000

#define APP_VERSION_MAJOR                               2
#define APP_VERSION_MIDDLE                   	        5
#define APP_VERSION_MINOR                               2

// #define PUBLISH_DATE                                "2022-7-11"   // "2022-6-30" // "2022-5-25" // "2022-3-30"
// #define PUBLISH_DATE                                "2022-11-08" //"2022-11-05" // "2022-10-12"  // "2022-8-2" 
// #define PUBLISH_DATE                                "2022-11-17"   
// #define PUBLISH_DATE                                "2022-12-10" 
// #define PUBLISH_DATE                                "2022-12-21" 
// #define PUBLISH_DATE                                "2023-01-06" 
// #define PUBLISH_DATE                                "2023-02-03" 
// #define PUBLISH_DATE                                "2023-02-10" 
// #define PUBLISH_DATE                                "2023-02-18" 
// #define PUBLISH_DATE                                "2023-06-16" 
// #define PUBLISH_DATE                                "2023-08-21" 
// #define PUBLISH_DATE                                "2023-09-27" 
// #define PUBLISH_DATE                                "2023-09-28" 
// #define PUBLISH_DATE                                "2023-10-18" 
// #define PUBLISH_DATE                                "2023-10-22"
// #define PUBLISH_DATE                                "2023-11-09"
// #define PUBLISH_DATE                                "2023-11-11"
// #define PUBLISH_DATE                                "2023-11-19"
// #define PUBLISH_DATE								   "2023-12-7"
// #define PUBLISH_DATE								   "2023-12-14"
// #define PUBLISH_DATE								   "2023-12-17"
//#define PUBLISH_DATE								   "2023-12-25"
//#define PUBLISH_DATE								   "2024-1-23"
//#define PUBLISH_DATE								   "2024-1-31"
//#define PUBLISH_DATE								   "2024-2-1"
//#define PUBLISH_DATE								   "2024-2-3"
//#define PUBLISH_DATE								   "2024-4-8"
#define PUBLISH_DATE								   "2024-4-25"

//#define BMS_MAIN_VER36 // At Lest 3.6Ver
//#define MASTER_VER        // BA通用版本
#define ND_VER_PROGRAM  // 南都版本
#define ND_VER_V359
//#define ND_VER_V360
//#define HAS_EMER_STOP_STRATEGY  // 有急停策略
#define MASTER_VER_CONF            // 汇流开关
#define RES_STRATEGY_COUNT     8  // 备用策略总个数
//#define DETECT_CONF_ERROR         // 检测汇流开关异常


//#define  ND_LD_PRJ  //南都娄底项目
//#define  LSZH_PRJ   //力神珠海项目 added 2021-5-9
//#define  GSHT_PRJ   // 甘肃华庭(南瑞PCS)  added 2021-5-27
//#define  LYGWK_PRJ  // 连云港威控项目-V3.4.7版
//#define  YW0357_PRJ // 亿纬0357 UPS项目2022-6-30
//#define  PGKS_PRJ     // 平高昆山/西团项目 2022-9-7
//#define  ND_HNXJ      // 南都华能新疆项目 2022-10-12
//#define  HJ_5MWH      // 宏景5MWH时项目(广东湛江粤水电5MW-5MWH) 2022-10-15
//#define  NDHZ_PRJ      // 南都惠州项目 2024-2-1

#define RUN_LOG_MODBUS_DEV           190  //设备 modbus 报文
#define RUN_LOG_MESSAGE_DEV          200  //设备 操作报文
#define RUN_LOG_FAILED_DEV           210  //设备 操作失败报文?
#define MAX_IODEV_COUNT              1    // IO模块总个数
// #define HAS_SECOND_IO_DEV
// #define READ_OTHER_DATA            // 读取其他可燃气体,空调等数据

//电池组信息
typedef struct BattGroupPara
{
	QString       devType;         //设备类型
	QString       devInstCode;     //电池组所在BA设备实例号
	unsigned int  modbusAddr;      //modbus地址
	unsigned long batCnt;          //电池节数
	unsigned long tempCnt;         //温度个数
}BattGroupPara;

//电池堆信息
typedef struct BattStackPara
{
	QString       devType;     //设备类型
	QString       devInstCode; //电池堆实例号
	unsigned int  modbusAddr;  //modbus地址
	unsigned int  groupCount;  //电池组数，堆不算在内
}BattStackPara;

// added 2020-8-27
// DI配置策略
typedef struct
{
	unsigned int		diIndex;   // DI索引，从0开始编号
	unsigned int		iStrategy; // 1:汇流开关反馈 9:消防采集干结点 
}DIStrategy;

// DO配置策略
typedef struct
{
	unsigned int		doIndex;   // DO索引，从0开始编号
	unsigned int		iStrategy; /* 1:故障灯或故障干结点; 2:禁充干结点; 3:禁放干结点; 
	9:消防动作干结点; 101:汇流开关合闸干结点 102:汇流开关分闸干结点 */
}DOStrategy;

/*			
// 消防配置策略
typedef struct
{
	unsigned int		diIndex;    // DI索引，从0开始编号
	unsigned char       alarmValue; // 1表示常开信号，为1时（闭合时)表示发生告警  0表示常闭信号，为0时（断开时)表示发生告警
	QList<DOStrategy>	xfCtrlList; // 消防动作干结点列表
}XFStrategy;

// 防雷配置策略
typedef struct
{
	unsigned int		diIndex;    // DI索引，从0开始编号
	unsigned char       alarmValue; // 1表示常开信号，为1时（闭合时)表示发生告警  0表示常闭信号，为0时（断开时)表示发生告警
	QList<DOStrategy>	tdCtrlList; // 防雷动作干结点列表
}ThunderStrategy;

// 急停配置策略
typedef struct
{
	unsigned int		diIndex;    // DI索引，从0开始编号
	unsigned char       alarmValue; // 1表示常开信号，为1时（闭合时)表示发生告警  0表示常闭信号，为0时（断开时)表示发生告警
}EmergStopStrategy;
*/

typedef struct
{
	unsigned int  diIndex;     // DI索引，从0开始编号
	unsigned char alarmValue;  // 1表示常开信号，为1时（闭合时)表示发生告警  0表示常闭信号，为0时（断开时)表示发生告警
}DI_STU;

// 消防配置策略 防雷配置策略 急停配置策略
typedef struct
{
	QList<DI_STU>	    diList;     // 采集DI列表
	QList<DOStrategy>	xfCtrlList; // 动作干结点列表
	int  confirmedCount;            // 告警确认次数
	QString             diName;     // 告警名称
	QString             diOverName; // 告警结束名称
}XFStrategy;

// modified 2021-09-19 加入检测多个反馈，如亿纬尼日尔630A，是一个DO口同时去控制两个断路器脱扣
// modified 2021-10-07 加入控制多个断路器分励脱扣，如平高大庆项目，是同时去控制两个DO口分励脱扣
// 汇流开关配置策略
typedef struct
{
	//unsigned int		diIndex;   // 汇流开关反馈DI索引，从0开始编号
	QList<DI_STU>		diCfgList; // 汇流开关反馈DI索引，从0开始编号 // modified 2021-06-22 加入判断常开常闭(娄底项目为常闭) 
	QList<int>	        hzDoList; // 合闸DO索引，从0开始编号
	QList<int>	        fzDoList; // 故障时分闸DO索引，从0开始编号
	
	QList<int>          xfTkDoList;// 消防脱扣干结点
	QList<int>          xfSprayTkDoList;// 消防喷洒脱扣干结点  // added 2022-12-10
	QList<int>	        volDownProtFzDoList; // 低电压保护时分闸DO索引，从0开始编号 // added 2022-1-15
}HLKGStrategy;
//add end

//干结点信息
typedef struct _DryData
{
	//int dbModbusAddr;
    //int devAddr;

	int  zz404D_addr;     // 4路继电器输出4路开关量输入 设备地址
	int  diStartRegAddr;  // DI起始寄存器地址
	int  doStartRegAddr;  // DO起始寄存器地址
	int  devDoCount;	  // ZZ-IO的输出干结点总个数
	int  devDiCount;	  // ZZ-IO的输入干结点总个数
	float tkDelayTime;	  // 控制合闸分闸时，延时时间，单位：秒
	float rwTimeoutSec;   // IO模块读写超时时间，单位：秒 //added 2022-1-11
	
    quint16 failedCount;// 通信失败次数
    quint16 readDiCount;// 读取到DI次数

	quint16 IOCtrl;    // 读取到DO值
	quint16 DIVal;     // 读取到DI值
	quint16 usErrorLen;// 错误报文长度 added 2023-11-17
	char errorBuf[50]; // 错误报文
    //char DIData[8];
	//char DOData[8];

	//bool  bReadDiFlag; // 是否已经获取到DI状态
	//bool  bReadDoFlag; // 是否已经获取到DO状态
}DryData;

// 气体控制探测设备数据结构体
typedef struct AirPara
{
	quint16   deviceModbusAddr;        //设备地址
	quint16 failedCount; // 通信失败次数
	quint16 connError;  // 通信是否正常    0 - 通信正常   1 - 通信故障
	QString mode;  // 支持模式CRT DCS IOT

	quint16 gasVal; // 浓度值
	quint16 gasUnit;	// 单位 0：%LEL 1：ppm 2：V/V 3：kppm 4：ppb 5：%FS
	quint16 alarmVal;  // 报警状态
	quint16 valid; // 是否无效。1 无效，0 有效
	char aLastAlarmLevel;  // 上一次的报警状态 

	quint16 value[20];  // 浓度值
	char aAlarmLevel1[20];  // 报警一级
	char aAlarmLevel2[20];  // 报警二级
	char aFault[20];  // 故障位
	char aShield[20];  //屏蔽位

	char aLastAlarmLevel1;  // 最近的报警一级状态
	char aLastAlarmLevel2;  // 最近的报警二级状态
	char aLastFault; // 最近的故障位
	quint16 lastconnFlag;  // 最近的通信是否正常    0 - 通信正常   1 - 通信故障	
}AirPara;

class CRTDB;
class DryCtrlThread;
class KgGlobalData
{
public:
	KgGlobalData(void);
	~KgGlobalData(void);
    static int readConfig();     //读取参数配置
	static int InitRtdb();         //初始化Rtdb
    
	static  QString ms_comDevName;   // BA与串口继电器通信接口，默认为:ttySAC2
	static  int  ms_zz404D_addr;     // 4路继电器输出4路开关量输入 设备地址
	static  int  ms_devNo;           // 设备编号(从1开始编号)
	static  int  ms_hzEnabled;       // 是否使能合闸
	static  int  ms_emgTkEnabled;    // 急停脱扣是否使能 added 2023-12-14
	static  int  ms_diStartRegAddr;  // DI起始寄存器地址
	static  int  ms_doStartRegAddr;  // DO起始寄存器地址
	static  int  ms_execFltkFirst;    // 分励脱扣是否优先执行
	static  int  ms_ctrlConfSwitchCount;// 先执行分励脱扣次数
	
	// added 2020-8-27
	static  int  ms_devDoCount;		 // ZZ-IO的输出干结点总个数
	static  int  ms_devDiCount;		 // ZZ-IO的输入干结点总个数
	static  float ms_tkDelayTime;	 // 控制合闸分闸时，延时时间，单位：秒
	static  float ms_rwTimeoutSec;   // IO模块读写超时时间，单位：秒 //added 2022-1-11
	//static  int  ms_reverseOrder;    // 解析数据时是否反字节 // added 2023-8-12
	static 	int	 ms_saveHlkgLog;	 // 保存汇流开关状态改变日志 
	static  int ms_isSaveDetaiLog;   // 是否输出详细日志
	static  QList<int> ms_diAlarmVals;
	static	QList<DOStrategy>	 ms_gzCtrlList;   // 故障动作干结点列表
	static	QList<DOStrategy>	 ms_alarmCtrlList;// 告警干结点列表
	static	QList<DOStrategy>	 ms_phbChgList;   // 禁充干结点列表
	static	QList<DOStrategy>	 ms_phbDischgList;// 禁放干结点列表
	static	QList<DOStrategy>	 ms_runCtrlList;  // 运行干结点列表
	static	QList<DOStrategy>	 ms_allLightCtrlList;  // 常亮灯列表
	static	QList<DOStrategy>	 ms_chgDriveList; // 充电驱动干结点列表 // added 2021-9-9
	static	QList<DOStrategy>	 ms_dchgDriveList;// 放电驱动干结点列表
	static	QList<DOStrategy>	 ms_bmsEmsCommFaultList;// BMS-EMS通信故障干结点列表 // added 2022-7-11
	static	QList<DOStrategy>	 ms_emgCtrlList; //   急停干结点列表
	static  QList<DOStrategy>    ms_bwGzCtrlList; // 并网故障干节点列表 // added 2023-6-14
	//static	QList<DOStrategy>	 ms_xfTkDriveList;// 消防脱扣干结点列表
	static  int 				 ms_diIndexChgDrive; // 充电接触器反馈
	static  int                  ms_diIndexDchgDrive;// 放电接触器反馈
	
	
	
	static  XFStrategy			 ms_xfStrategy;	    // 消防配置策略
	static  XFStrategy			 ms_xfSprayStrategy;// 消防喷洒配置策略 // added 2022-12-10
	static  XFStrategy			 ms_xfFaultStrategy;// 消防故障配置策略 // added 2022-12-21
	static  XFStrategy			 ms_xfManuAutoStrategy; // 消防手动/自动配置策略 // added 2023-11-9
	static  XFStrategy			 ms_elecPowerOffStrategy; // 市电断电 // added 2023-11-9
	static  XFStrategy			 ms_waterStrategy;  // 水浸配置策略
	static  XFStrategy		     ms_tdStrategy;	    // 防雷配置策略
	static  XFStrategy           ms_emgStopStrategy;// 急停配置策略
	static  XFStrategy			 ms_waterStrategySec;  // #2水浸配置策略
	static  XFStrategy		     ms_tdStrategySec;	   // #2防雷配置策略
	static  XFStrategy           ms_emgStopStrategySec;// #2急停配置策略
    static  XFStrategy           ms_bmsLocalStrategy; // BMS就地配置策略
	static  XFStrategy           ms_bmsRemmoteStrategy;// BMS远方配置策略
	static  XFStrategy           ms_acFaultStrategy;   // 空调机组故障策略
	static  XFStrategy           ms_lqFaultStrategy;   //液冷机组故障策略
	
	static  XFStrategy           ms_combusGasStrategy;// 可燃气体配置策略 combustible gas  //added 2021-12-7
	static  XFStrategy           ms_fuseStrategy;     // 熔断器配置策略   // added 2022-3-27
	static  XFStrategy           ms_xfMotionStrategy; // 消防释放配置策略 // added 2022-4-6
	static  XFStrategy           ms_xfWarmStrategy;   // 消防预警配置策略 // added 2022-6-8

	static  XFStrategy           ms_upsAlmStrategy;    // UPS告警配置策略 // added 2022-11-8
	static  XFStrategy           ms_doorAlmStrategy;   // 门禁告警配置策略 // added 2022-11-8
    static  XFStrategy           ms_doorAlmStrategySec; // 门禁
	static  XFStrategy			 ms_resStrategy[RES_STRATEGY_COUNT];     // 备用策略1 // added 2023-8-19
	
	static 	HLKGStrategy		 ms_hlkgStrategy;      // 汇流开关配置策略
	static  XFStrategy           ms_isolSwitchStrategy;// 隔离开关策略
	static  XFStrategy           ms_mainSwitchStrategy;// 主断路器(手动操作)策略
	static  int                  ms_connTimeoutCount; // 通迅故障确认次数
	static  int                  ms_repeatFzCount;     // 重复断开汇流开关次数 added 204-1-23
	// added end
	
    static  CRTDB *ms_pRTDB; 
	static  CBattStack *ms_pStack;

	static QString m_strDriver;      // DB Information
	static QString m_strIP; 
	static ushort m_usPort; 
	static QString m_strDBName; 
	static QString m_strUserName; 
	static QString m_strPwd;	

	static  int ms_installBankNum;//电池组总数
	static  int ms_bankNumInStack;// 堆管辖的电池组总数
    //static 	QList<BattGroupPara> ms_batGroupList;//电池组参数列表
	//static 	QList<BattStackPara> ms_batStackList;//电池堆参数列表

	static DryData ms_dryData;
	static DryData ms_drySecData;
	
    static int ms_isOutputLog;      // 是否输出日志 1：输出   其他值：不输出
	//static KgLogFile ms_logFile;
	static DryCtrlThread* ms_dryThd;

	static QString ms_IOConfigStr;        // added 2022-5-22
	//static int ms_hasUpsDryNode;          // added 2022-11-5
	static QList<AirPara>  ms_airList;//可燃气体探测设备列表
};

void   writeKgLogfile(QString strInfo);
UINT16 Modbus_CRC16(UINT8 *dat_buf,UINT16 dat_len);
void   getCurrentTime(int &h, int &m, int &s, int &msec);
int    NeedBreakJCQCount();        //获取需要断开接触器的电组池总组数 2019-10-12
int    NeedCloseJCQCount();        //获取需要闭合接触器的电组池总组数 2019-11-28
int    GetClosedJCQCount();		//获取正负接触器都闭合的电池组数 2020-5-5
int    GetOpenedJCQCount();//获取正负接触器都断开的电池组数 2020-5-19
void   SetBamsFireAlarm (char alarm); //通知消防告警到BAMS，BA运行状态由正常转为跳机，各组状态切换到开路
void   SetBamsWaterAlarm(char waterAlarm);//通知水浸告警到BAMS
void   SetFuseAlarm(char alarm);
void   SetIsolSwitchAggrState (char state);// 设置隔离开关状态 2021-5-27
void   SetEmergeStopAlarm(char alarm);// 通知BA紧急停机 2020-12-23
void   updateDryDataToRtdb(DryCtrlThread *pThread); // 更新DI1-4数据到BA的通用保持寄存器50-53中 2020-1-15
int    ExecDbQuery(QString strSql, QString &strError);//执行sql语句
void   saveFireAlarmToDb(int fireBankNo, int fireBoxNo);
void   updateAlarmOverToDb();
void   saveLogToBaDb(QString strLog);
int	   isBankInStack(int bankNo);//  判断电池组是否参与运算//added 2020-6-12
void   keepContCtrlOpened(int stackState, int hlkgState); // 汇流开关闭合且接触器断开时，控制接触器保持断开状态，不准闭合，直到汇流开关断开
int    isChLang();
int    isBankAlarm();      // 0：正常 1：报警 //added 2021-5-30
bool   hasVolDownPort(); // 有电压欠压保护 //added 2022-01-15
void   openDos(quint16 &IOCtrl, QList<int> doList);// 控制DO闭合 //added 2021-1-16
void   closeDos(quint16 &IOCtrl, QList<int> doList);// 控制DO断开
void   getInstallInfo(); // 获取安装组数 // added 2022-3-8
int    isBoxVolTempDiffAlarm(); // 有箱压差// added 2022-7-5
void   readFileDIDOConfig();
QString getAppVer();
QString kgConvert(char *str);